//
//  HLMessageListViewController.m
//  YueYue
//
//  Created by hulu001 on 2023/6/7.
//

#import "HLMessageListViewController.h"
#import <NIMSDK/NIMSDK.h>
#import "HLHomeRecommendRequest.h"
#import "HLMessageListHeaderView.h"
#import "HLMessageListCell.h"

@interface HLMessageListViewController ()
<NIMLoginManagerDelegate,
NIMConversationManagerDelegate,
NIMChatExtendManagerDelegate,
NIMChatManagerDelegate>
/**
 * 置顶的聊天
 */
@property(nonatomic, strong) NSMutableDictionary<NIMSession *,NIMStickTopSessionInfo *> *stickTopInfos;
/**
 *  删除会话时是不是也同时删除服务器会话 (防止漫游)
 */
@property (nonatomic, assign)   BOOL autoRemoveRemoteSession;
@property (nonatomic, strong)  HLMessageListHeaderView *headerView;

@end

@implementation HLMessageListViewController


- (instancetype)init;
{
    self = [super initWithStyle:UITableViewStyleGrouped];
    if (self){
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [[NIMSDK sharedSDK].loginManager addDelegate:self];
    [[NIMSDK sharedSDK].chatExtendManager addDelegate:self];
    [[NIMSDK sharedSDK].conversationManager addDelegate:self];
    
    [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(observeUpdateTopSession:) name:HLUpdateStickTopNotification object:@"1"];
    
    MJWeakSelf
    [NIMSDK.sharedSDK.chatExtendManager loadStickTopSessionInfos:^(NSError * _Nullable error, NSDictionary<NIMSession *,NIMStickTopSessionInfo *> * _Nullable infos) {
        weakSelf.stickTopInfos = [NSMutableDictionary dictionaryWithDictionary:infos];
        [weakSelf refresh];
    }];
    
    // 添加会话
    NIMAddEmptyRecentSessionBySessionOption *option = [NIMAddEmptyRecentSessionBySessionOption.alloc init];
    option.withLastMsg = YES;
    option.addEmptyMsgIfNoLastMsgExist = YES;
    [NIMSDK.sharedSDK.conversationManager addEmptyRecentSessionBySession:[NIMSession session:@"1" type:NIMSessionTypeP2P] option:option];
    
    [self refresh];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (self.datasources.count > 0){
        [self.tableView reloadData];
    }
}



- (void)observeUpdateTopSession:(NSNotification *)notifi
{
    NIMStickTopSessionInfo *newInfo = notifi.userInfo[@"key"];
    NSString *type = notifi.userInfo[@"type"];
    if ([type isEqualToString:@"1"]){
        self.stickTopInfos[newInfo.session] = newInfo;
    } else {
        self.stickTopInfos[newInfo.session] = nil;
    }
    [self refresh];
}

#pragma mark - Private

- (void)refresh
{
    
    [self.datasources removeAllObjects];
    [self.datasources addObjectsFromArray:[NIMSDK sharedSDK].conversationManager.allRecentSessions];
    
    [NIMSDK.sharedSDK.chatExtendManager sortRecentSessions:self.datasources withStickTopInfos:self.stickTopInfos];
    
    [self.datasources sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        NIMRecentSession *item1 = obj1;
        NIMRecentSession *item2 = obj2;
        
        // 官方号
        if ([HLHelper IMFilterWithSessionId:item1.session.sessionId]) {
            return NSOrderedAscending;
        }
        
        if ([HLHelper IMFilterWithSessionId:item2.session.sessionId]) {
            return NSOrderedDescending;
        }
        
        // 置顶
        if (self.stickTopInfos[item2.session] && self.stickTopInfos[item1.session]) {
            if (item1.lastMessage.timestamp < item2.lastMessage.timestamp) {
                return NSOrderedDescending;
            }
            if (item1.lastMessage.timestamp > item2.lastMessage.timestamp) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;
        } else if (self.stickTopInfos[item2.session]) {
            return NSOrderedDescending;
        } else if (self.stickTopInfos[item1.session]) {
            return NSOrderedAscending;
        } else {
            if (item1.lastMessage.timestamp < item2.lastMessage.timestamp) {
                return NSOrderedDescending;
            }
            if (item1.lastMessage.timestamp > item2.lastMessage.timestamp) {
                return NSOrderedAscending;
            }
            return NSOrderedSame;
        }
    }];
    [self.tableView reloadData];
}

- (void)initTableView
{
    [super initTableView];
    [self.tableView registerClass:[HLMessageListCell class] forCellReuseIdentifier:[HLMessageListCell identifyCell]];
    [self.tableView registerClass:[HLMessageListHeaderView class] forHeaderFooterViewReuseIdentifier:[HLMessageListHeaderView identifyCell]];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.datasources.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    HLMessageListCell *cell = [tableView dequeueReusableCellWithIdentifier:[HLMessageListCell identifyCell]];
    cell.model = self.datasources[indexPath.row];
    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NIMRecentSession *item = self.datasources[indexPath.row];
    [HLUIHelper showSessionViewControllerWithSession:item.session];
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (!self.headerView && ![HLRunTime shareInstance].isFood){
        self.headerView= [tableView dequeueReusableHeaderFooterViewWithIdentifier:[HLMessageListHeaderView identifyCell]];
        _headerView.videoView.recommendType = HLHomeRecommendTypeMessage;
    }
    return _headerView;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

- (UISwipeActionsConfiguration *)tableView:(UITableView *)tableView trailingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NIMRecentSession *recent = self.datasources[indexPath.row];
    if ([HLHelper IMFilterWithSessionId:recent.session.sessionId]){
        return  [UISwipeActionsConfiguration configurationWithActions:@[]];;
    }
    BOOL isTop = self.stickTopInfos[recent.session] != nil;
    
    MJWeakSelf
    UIContextualAction *deleteAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title:@"删除" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
        [weakSelf deleteAllRemoteMessagesWithSession:recent];
        if (isTop){
            [weakSelf removeStickTopWithSession:recent];
        }
    }];
    deleteAction.backgroundColor = UIColorRed;

    
    UIContextualAction *topAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal title: isTop ? @"取消置顶": @"置顶" handler:^(UIContextualAction * _Nonnull action, __kindof UIView * _Nonnull sourceView, void (^ _Nonnull completionHandler)(BOOL)) {
        if (isTop){
            [weakSelf removeStickTopWithSession:recent];
        } else {
            [weakSelf addStickTopWithSession:recent];
        }
    }];
    topAction.backgroundColor = HLMainColor;
    
    UISwipeActionsConfiguration *Configuration = [UISwipeActionsConfiguration configurationWithActions:@[deleteAction, topAction]];
    Configuration.performsFirstActionWithFullSwipe = NO;
    return Configuration;
}

- (void)dealloc
{
    [[NIMSDK sharedSDK].loginManager removeDelegate:self];
    [[NIMSDK sharedSDK].chatExtendManager removeDelegate:self];
    [[NIMSDK sharedSDK].conversationManager removeDelegate:self];
    [NSNotificationCenter.defaultCenter removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}

#pragma mark - <私有方法>
- (void)deleteAllRemoteMessagesWithSession:(NIMRecentSession *)recent
{
    MJWeakSelf
    id<NIMConversationManager> manager = [[NIMSDK sharedSDK] conversationManager];
    // 1、清空本地和远端的聊天数据
    NIMSessionDeleteAllRemoteMessagesOptions *opt = [[NIMSessionDeleteAllRemoteMessagesOptions alloc] init];
    [manager deleteAllRemoteMessagesInSession:recent.session options:opt completion:^(NSError * _Nullable error) {
        
        if (!error) {
            // 2、删除最近会话
            NIMDeleteRecentSessionOption *option = [[NIMDeleteRecentSessionOption alloc] init];
            [manager deleteRecentSession:recent option:option completion:^(NSError * _Nullable error) {
            }];
            [weakSelf refresh];
        }
        
    }];
}

- (void)removeStickTopWithSession:(NIMRecentSession *)recent
{
    // 删除置顶
    MJWeakSelf
    NIMStickTopSessionInfo *stickTopInfo = [NIMSDK.sharedSDK.chatExtendManager stickTopInfoForSession:recent.session];
    if (stickTopInfo) {
        [NIMSDK.sharedSDK.chatExtendManager removeStickTopSession:stickTopInfo completion:^(NSError * _Nullable error, NIMStickTopSessionInfo * _Nullable removedInfo) {
            if (!error) {
                weakSelf.stickTopInfos[recent.session] = nil;
                [weakSelf refresh];
            }
        }];
    }
}

- (void)addStickTopWithSession:(NIMRecentSession *)recent
{
    MJWeakSelf
    NIMAddStickTopSessionParams *params = [[NIMAddStickTopSessionParams alloc] initWithSession:recent.session];
    [NIMSDK.sharedSDK.chatExtendManager addStickTopSession:params completion:^(NSError * _Nullable error, NIMStickTopSessionInfo * _Nullable newInfo) {
        if (error) {
            [QMUITips showWithText:error.localizedDescription];
            return;
        }
        weakSelf.stickTopInfos[newInfo.session] = newInfo;
        [weakSelf refresh];
    }];
}

#pragma mark - <NIMSDK NIMConversationManagerDelegate>

- (void)onMarkMessageReadCompleteInSession:(NIMSession *)session error:(NSError *)error {
    if (error) {
        NSString *msg = [NSString stringWithFormat:@"session %@ type %@ mark fail.code:%@",
                         session.sessionId, @(session.sessionType), @(error.code)];
        [QMUITips showWithText:msg];
    }
}

- (void)didLoadAllRecentSessionCompletion
{
    [self refresh];
}

- (void)didAddRecentSession:(NIMRecentSession *)recentSession
           totalUnreadCount:(NSInteger)totalUnreadCount{
    [self refresh];
}

- (void)didUpdateRecentSession:(NIMRecentSession *)recentSession
              totalUnreadCount:(NSInteger)totalUnreadCount{
    
    [self refresh];
}

- (void)didRemoveRecentSession:(NIMRecentSession *)recentSession
              totalUnreadCount:(NSInteger)totalUnreadCount
{
    //如果删除本地会话后就不允许漫游当前会话，则需要进行一次删除服务器会话的操作
    if (self.autoRemoveRemoteSession)
    {
        [[NIMSDK sharedSDK].conversationManager deleteRemoteSessions:@[recentSession.session]
                           completion:nil];
    }
    [self refresh];
}

- (void)messagesDeletedInSession:(NIMSession *)session
{
    [self refresh];
}

- (void)allMessagesDeleted{
    [self refresh];
}

- (void)allMessagesRead
{
    [self refresh];
}

#pragma mark - NIMLoginManagerDelegate

- (void)onLogin:(NIMLoginStep)step
{
    switch (step) {
        case NIMLoginStepLinkFailed: // 连接服务器失败
        case NIMLoginStepLoginFailed:// 登录失败
        case NIMLoginStepLoseConnection:// 连接断开
        {
            [self emptyTipView];
        }
            break;
        case NIMLoginStepLoginOK: // 登录成功
        {
            [self hideEmptyView];
        }
            break;
        case NIMLoginStepNetChanged:
        {
            if (![NIMSDK.sharedSDK.loginManager isLogined]) {
                [self emptyTipView];
            } else {
                [self hideEmptyView];
            }
        }
            
        default:
            break;
    }
    [self refresh];
}

- (void)emptyTipView
{
    if (self.datasources.count > 0){
        return;
    }
    [self showEmptyView];
    [self.emptyView setLoadingViewHidden:YES];
    [self.emptyView setImage:UIImageMake(@"empty_icon_1")];
    [self.emptyView setImageViewInsets:UIEdgeInsetsMake(116, 0, 16, 0)];
    [self.emptyView setTextLabelText:@"别慌，一点小意外"];
    [self.emptyView setDetailTextLabelText:@"请确认网络安全后，再次刷新试试"];
    [self.emptyView setActionButtonTitle:@"刷新"];
    [self.emptyView setActionButtonTitleColor:UIColorWhite];
    [self.emptyView.actionButton setBackgroundColor:HLMainColor];
    [self.emptyView.actionButton setContentEdgeInsets:UIEdgeInsetsMake(10, 50, 10, 50)];
    [self.emptyView.actionButton setCornerRadius:20];
    [self.emptyView.actionButton addTarget:self action:@selector(refresh) forControlEvents:UIControlEventTouchUpInside];
}


#pragma mark - JXCategoryListContentViewDelegate

/**
 实现 <JXCategoryListContentViewDelegate> 协议方法，返回该视图控制器所拥有的「视图」
 */
- (UIView *)listView {
    return self.view;
}


@end
